home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 19
/
Aminet 19 (1997)(GTI - Schatztruhe)[!][Jun 1997].iso
/
Aminet
/
gfx
/
conv
/
DumpDTAnim013.lha
/
dumpdtanim
/
dumpdtanim.c
< prev
next >
Wrap
C/C++ Source or Header
|
1997-01-05
|
42KB
|
1,333 lines
/*
**
** $VER: dumpdtanim.c 1.3 (5.1.97)
** dumpdtanim 1.3
**
** main file
**
** (C) Copyright 1996/97 by Roland 'Gizzy' Mainz
** All Rights Reserved
**
*/
/* amiga includes */
#include <exec/types.h>
#include <exec/memory.h>
#include <exec/execbase.h>
#include <exec/libraries.h>
#include <dos/dos.h>
#include <dos/dosextens.h>
#include <datatypes/datatypes.h>
#include <datatypes/datatypesclass.h>
#include <datatypes/soundclass.h>
#include <datatypes/pictureclass.h>
#include <datatypes/animationclass.h>
#include <workbench/workbench.h>
/* amiga prototypes */
#include <clib/macros.h>
#include <clib/exec_protos.h>
#include <clib/dos_protos.h>
#include <clib/iffparse_protos.h>
#include <clib/icon_protos.h>
#include <clib/graphics_protos.h>
#include <clib/intuition_protos.h>
#include <clib/datatypes_protos.h>
#include <clib/dtclass_protos.h>
#include <clib/alib_protos.h>
/* amiga pragmas */
#include <pragmas/exec_pragmas.h>
#include <pragmas/dos_pragmas.h>
#include <pragmas/iffparse_pragmas.h>
#include <pragmas/icon_pragmas.h>
#include <pragmas/graphics_pragmas.h>
#include <pragmas/intuition_pragmas.h>
#include <pragmas/datatypes_pragmas.h>
#include <pragmas/dtclass_pragmas.h>
/* ansi includes */
#include <string.h>
/*****************************************************************************/
/* IFF FILM ID */
#ifndef ID_FILM
#define ID_FILM MAKE_ID( 'F', 'I', 'L', 'M' )
#endif /* !ID_FILM */
/* CAT CELL, a single IFF FILM frame (bitmap and sound) */
#ifndef ID_CELL
#define ID_CELL MAKE_ID( 'C', 'E', 'L', 'L' )
#endif /* !ID_CELL */
/* body, used by CELLs ILBM and 8SVX */
#ifndef ID_BODY
#define ID_BODY MAKE_ID( 'B', 'O', 'D', 'Y' )
#endif /* !ID_BODY */
/* IFF ILBM */
#ifndef ID_ILBM
#define ID_ILBM MAKE_ID( 'I', 'L', 'B', 'M' )
#endif /* !ID_ILBM */
/* ILBM BMHD (bitmap header) */
#ifndef ID_BMHD
#define ID_BMHD MAKE_ID( 'B', 'M', 'H', 'D' )
#endif /* !ID_BMHD */
/* ILBM CMAP (color map) */
#ifndef ID_CMAP
#define ID_CMAP MAKE_ID( 'C', 'M', 'A', 'P' )
#endif /* !ID_CMAP */
/* ILBM CAMG (view mode id) */
#ifndef ID_CAMG
#define ID_CAMG MAKE_ID( 'C', 'A', 'M', 'G' )
#endif /* !ID_CMAP */
/* IFF 8SVX */
#ifndef ID_8SVX
#define ID_8SVX MAKE_ID( '8', 'S', 'V', 'X' )
#endif /* !ID_8SVX */
/* 8SVX VHDR (VoiceHeader) */
#ifndef ID_VHDR
#define ID_VHDR MAKE_ID( 'V', 'H', 'D', 'R' )
#endif /* !ID_VHDR */
/* 8SVX CHAN (left/right/stereo channel) */
#ifndef ID_CHAN
#define CHAN_RIGHT (4L)
#define CHAN_LEFT (2L)
#define CHAN_STEREO (6L) /* CHAN_RIGHT + CHAN_LEFT */
#define ID_CHAN MAKE_ID( 'C', 'H', 'A', 'N' )
#endif /* !ID_CHAN */
/*****************************************************************************/
/* from <iffp/ilbm.h>*/
/* BMHD flags */
/* Advisory that 8 significant bits-per-gun have been stored in CMAP
* i.e. that the CMAP is definitely not 4-bit values shifted left.
* This bit will disable nibble examination by color loading routine.
*/
#define BMHDB_CMAPOK (7U)
#define BMHDF_CMAPOK (1U << BMHDB_CMAPOK)
/*****************************************************************************/
extern struct ExecBase *SysBase;
extern struct Library *DOSBase;
struct Library *IFFParseBase;
struct Library *IconBase;
struct Library *GfxBase;
struct Library *IntuitionBase;
struct Library *DataTypesBase;
/*****************************************************************************/
#define TEMPLATE "NAME/A," \
"MOVIE/S," \
"STARTFRAME/K/N," \
"STOPFRAME/K/N," \
"SKIPFRAMES/K/N," \
"IFFFILM=FILM/K," \
"CLIPIFFFILM=CLIPFILM/S," \
"CLIPIFFFILMUNIT=CLIPFILMUNIT/K/N," \
"PICTUREPERFRAME/S," \
"SAMPLEPERFRAME=SPF/S," \
"GLOBALSAMPLE/S"
#define OPT_NAME (0)
#define OPT_MOVIE (1)
#define OPT_STARTFRAME (2)
#define OPT_STOPFRAME (3)
#define OPT_SKIPFRAMES (4)
#define OPT_IFFFILM (5)
#define OPT_CLIPIFFFILM (6)
#define OPT_CLIPIFFFILMUNIT (7)
#define OPT_PICTUREPERFRAME (8)
#define OPT_SAMPLEPERFRAME (9)
#define OPT_GLOBALSAMPLE (10)
#define NUM_OPTS (11)
/*****************************************************************************/
/* prototypes */
long main( void );
struct IFFHandle *OpenIFFFile( STRPTR, ULONG );
BOOL CloseIFFFile( struct IFFHandle * );
struct IFFHandle *OpenIFFClipboard( LONG );
void CloseIFFClipboard( struct IFFHandle * );
LONG StartIFFFilm( struct IFFHandle *, struct BitMapHeader *, ULONG, struct ColorRegister *, ULONG, struct VoiceHeader * );
void EndIFFFilm( struct IFFHandle * );
LONG WriteIFFFilmCell( struct IFFHandle *, struct BitMapHeader *, struct BitMap *, BYTE *, ULONG );
LONG Put8SVXBody( struct IFFHandle *, BYTE *, ULONG );
LONG PutILBMBody( struct IFFHandle *, struct BitMap *, struct BitMapHeader * );
ULONG SaveDTObject( Object *, struct Window *, struct Requester *, STRPTR, ULONG, struct TagItem * );
void SaveSample( STRPTR, BYTE *, ULONG, ULONG, ULONG );
void FillColorRegisters( struct ColorRegister *, ULONG *, ULONG );
void CopyBitMap( struct BitMap *, struct BitMap * );
void mysprintf( STRPTR, STRPTR , ... );
BOOL IsInterleavedBitMap( struct BitMap * );
/*****************************************************************************/
/* IFF errors to DOS errors */
LONG ifferr2doserr[] =
{
0L, /* End of file (not an error). */
0L, /* End of context (not an error). */
DTERROR_INVALID_DATA, /* No lexical scope. */
ERROR_NO_FREE_STORE, /* Insufficient memory. */
ERROR_SEEK_ERROR, /* Stream read error. */
ERROR_SEEK_ERROR, /* Stream write error. */
ERROR_SEEK_ERROR, /* Stream seek error. */
DTERROR_INVALID_DATA, /* File is corrupt. */
DTERROR_INVALID_DATA, /* IFF syntax error. */
ERROR_OBJECT_WRONG_TYPE, /* Not an IFF file. */
ERROR_REQUIRED_ARG_MISSING, /* Required call-back hook missing. */
(0xDEADDEADUL) /* Return to client. You should never see this */
};
/*****************************************************************************/
long main( void )
{
/* Argument parsing variables */
LONG options[ NUM_OPTS ];
struct RDArgs *rdargs;
LONG error = 0L;
memset( options, 0, sizeof( options ) );
IFFParseBase = OpenLibrary( "iffparse.library", 39UL );
IconBase = OpenLibrary( "icon.library", 39UL );
GfxBase = OpenLibrary( "graphics.library", 39UL );
IntuitionBase = OpenLibrary( "intuition.library", 39UL );
DataTypesBase = OpenLibrary( "datatypes.library", 39UL );
if( IFFParseBase && IconBase && GfxBase && IntuitionBase && DataTypesBase )
{
if( rdargs = ReadArgs( TEMPLATE, options, NULL ) )
{
STRPTR filepart = FilePart( (STRPTR)options[ OPT_NAME ] );
ULONG startframe = 0UL, /* start at this frame */
stopframe = ~0UL, /* stop at this frame */
skipframes = 1UL; /* skip n frames during scan */
struct IFFHandle *ifffilm = NULL, /* IFF FILM output stream (file) */
*clipifffilm = NULL; /* IFF FILM output stream (clipboard) */
Object *o; /* anim/movie object */
if( options[ OPT_STARTFRAME ] )
{
startframe = *((LONG *)options[ OPT_STARTFRAME ]);
}
if( options[ OPT_STOPFRAME ] )
{
stopframe = *((LONG *)options[ OPT_STOPFRAME ]);
if( stopframe < 1UL )
{
stopframe = 1UL;
}
}
if( options[ OPT_SKIPFRAMES ] )
{
skipframes = *((LONG *)options[ OPT_SKIPFRAMES ]);
if( skipframes < 1UL )
{
skipframes = 1UL;
}
}
/* Open the animation/movie object */
if( o = NewDTObject( (APTR)options[ OPT_NAME ],
/* We will only accept sound DataTypes */
DTA_GroupID, ((options[ OPT_MOVIE ])?(GID_MOVIE):(GID_ANIMATION)),
/* No more attributes */
TAG_DONE ) )
{
struct gpLayout gpl;
/* Base information */
STRPTR objname;
/* Animation related */
ULONG animwidth, /* width of animation */
animheight, /* height of animation */
animdepth; /* depth of animation */
ULONG anumframes = 0UL; /* number of frames in animation */
ULONG afps = 0UL;
/* Anim frame loading */
struct adtFrame alf; /* method msg for ADTM_LOADFRAME */
ULONG timestamp; /* timestamp to load */
/* Animation frame picture related */
ULONG amodeid; /* mode id of animation */
struct BitMapHeader *abmh; /* bitmapheader of animation */
ULONG anumcolors; /* number of colors in animation */
ULONG *acregs; /* ADTA_CRegs */
struct ColorRegister *acm; /* ADTA_ColorRegisters struct ColorRegister array */
TEXT picturefilename[ 512 ]; /* buffer for filename when writing */
/* Anim frame sample related */
BYTE *asample;
ULONG asamplelength = 0UL;
ULONG aperiod;
ULONG acycles;
TEXT samplefilename[ 512 ];
/* Sample build from all samples */
BYTE *globalsample = NULL;
ULONG globalsampleoffset = 0UL;
ULONG globalsamplesize = 0UL;
/* Get information about the object */
if( GetDTAttrs( o, DTA_ObjName, (&objname),
ADTA_Width, (&animwidth),
ADTA_Height, (&animheight),
ADTA_Depth, (&animdepth),
ADTA_Frames, (&anumframes),
ADTA_FramesPerSecond, (&afps),
ADTA_ModeID, (&amodeid),
PDTA_BitMapHeader, (&abmh),
ADTA_NumColors, (&anumcolors),
ADTA_CRegs, (&acregs),
ADTA_ColorRegisters, (&acm),
ADTA_Cycles, (&acycles),
ADTA_Period, (&aperiod),
ADTA_Sample, (&asample),
ADTA_SampleLength, (&asamplelength),
TAG_DONE ) != 15UL )
{
Printf( "*** warning: not enough attributes to get\n" );
}
/* Sound available ? */
if( asamplelength && aperiod )
{
struct VoiceHeader vh;
vh . vh_OneShotHiSamples = asamplelength;
vh . vh_RepeatHiSamples = 0UL;
vh . vh_SamplesPerHiCycle = 0UL;
vh . vh_SamplesPerSec = ((SysBase -> ex_EClockFrequency) * 5UL) / aperiod;
vh . vh_Octaves = 1UL;
vh . vh_Compression = CMP_NONE;
vh . vh_Volume = 0x10000UL; /* maximum volume */
if( options[ OPT_IFFFILM ] )
{
if( ifffilm = OpenIFFFile( (STRPTR)options[ OPT_IFFFILM ], MODE_NEWFILE ) )
{
if( error = StartIFFFilm( ifffilm, abmh, amodeid, acm, anumcolors, (&vh) ) )
{
Printf( "error while writing IFF FILM to file%ld\n", error );
CloseIFFFile( ifffilm );
ifffilm = NULL;
}
else
{
Printf( "writing IFF FILM stream to file %s\n", (STRPTR)options[ OPT_IFFFILM ] );
}
}
else
{
Printf( "can't open iff file\n" );
error = IoErr();
}
}
if( options[ OPT_CLIPIFFFILM ] )
{
LONG unit;
if( options[ OPT_CLIPIFFFILMUNIT ] )
{
unit = *((LONG *)options[ OPT_CLIPIFFFILMUNIT ]);
}
else
{
unit = PRIMARY_CLIP;
}
if( clipifffilm = OpenIFFClipboard( unit ) )
{
if( error = StartIFFFilm( clipifffilm, abmh, amodeid, acm, anumcolors, (&vh) ) )
{
Printf( "error while writing IFF FILM to clipboard %ld\n", error );
CloseIFFClipboard( clipifffilm );
clipifffilm = NULL;
}
else
{
Printf( "writing IFF FILM stream to clipboard unit %ld\n", unit );
}
}
else
{
Printf( "can't open iff clipboard\n" );
error = IoErr();
}
}
if( options[ OPT_GLOBALSAMPLE ] )
{
globalsamplesize = (((asamplelength + 10UL) * anumframes) + 1024UL);
globalsample = (BYTE *)AllocVec( globalsamplesize, MEMF_PUBLIC );
}
}
else
{
if( options[ OPT_IFFFILM ] || options[ OPT_CLIPIFFFILM ] )
{
Printf( "can't create IFF FILM stream because sound is missing\n" );
error = ERROR_OBJECT_WRONG_TYPE;
}
if( options[ OPT_GLOBALSAMPLE ] )
{
Printf( "can't create global sample because sound is missing\n" );
error = ERROR_OBJECT_WRONG_TYPE;
}
}
/* Display any information we obtained */
if( objname )
{
Printf( "Name: \"%s\"\n", objname );
}
/* Print info... */
Printf( "width %lu height %lu depth %lu frames %lu\n"
"FramesPerSecond %lu modeid %lx colors %lu\n"
"sample %lx samplelength %lu cycles %lu period %lu\n",
animwidth, animheight, animdepth, anumframes,
afps, amodeid, anumcolors,
asample, asamplelength, acycles, aperiod );
/* "Layout" animation (for those anim classes which need this,
* __NOT__ recommened)
*/
gpl . MethodID = DTM_PROCLAYOUT;
gpl . gpl_GInfo = NULL;
gpl . gpl_Initial = 1L;
DoMethodA( o, (Msg)(&gpl) );
/* Start scan through animation */
for( timestamp = startframe ; (timestamp < anumframes) && (timestamp <= stopframe) ; timestamp += skipframes )
{
/* On error break */
if( error )
{
break;
}
/* Check for CTRL_C signal... */
if( SetSignal( 0UL, 0UL ) & SIGBREAKF_CTRL_C )
{
error = ERROR_BREAK;
break;
}
/* reset method msg */
memset( (void *)(&alf), 0, sizeof( struct adtFrame ) );
/* load frame */
alf . MethodID = ADTM_LOADFRAME;
alf . alf_TimeStamp = timestamp;
alf . alf_Frame = timestamp;
DoMethodA( o, (Msg)(&alf) );
/* print frame contents */
Printf( "frame: timestamp %lu frame %lu duration %lu bitmap %lx cmap %lx sample %lx len %lu period %lu\n",
timestamp,
(alf . alf_Frame),
(alf . alf_Duration),
(alf . alf_BitMap),
(alf . alf_CMap),
(alf . alf_Sample),
(alf . alf_SampleLength),
(alf . alf_Period) );
/* handle picture data */
if( abmh && (alf . alf_BitMap) && options[ OPT_PICTUREPERFRAME ] )
{
ULONG framewidth,
frameheight,
framedepth;
struct BitMap *bm;
/* bitmap dimensions may not match ADTA_(Width|Height|Depth) dimentions */
framewidth = GetBitMapAttr( (alf . alf_BitMap), BMA_WIDTH );
frameheight = GetBitMapAttr( (alf . alf_BitMap), BMA_HEIGHT );
framedepth = GetBitMapAttr( (alf . alf_BitMap), BMA_DEPTH );
/* Correct bitmap width if the OS didn't noticed that this is an interleaved bm
* GetBitMapAttr( bm, BMA_WIDTH ) will return (width * depth) instead of width.
* The following code should be future-compatible...
*/
if( (!(GetBitMapAttr( (alf . alf_BitMap), BMA_FLAGS ) & BMF_INTERLEAVED)) &&
IsInterleavedBitMap( (alf . alf_BitMap) ) )
{
framewidth /= framedepth;
}
/* Here we must allocate a temp chip mem bitmap because animation frames can be
* outside CHIP-MEM and picture.datatype cannot deal with non-chip-mem bitmaps...
*/
if( bm = AllocBitMap( framewidth, frameheight, framedepth, 0UL, (alf . alf_BitMap) ) )
{
Object *po;
/* Copy bitmap */
CopyBitMap( bm, (alf . alf_BitMap) );
/* Create picture object and set it up manually (e.g. DTST_RAM) */
if( po = NewDTObject( NULL,
DTA_SourceType, DTST_RAM,
DTA_GroupID, GID_PICTURE,
TAG_DONE ) )
{
struct BitMapHeader *pbmh;
if( GetDTAttrs( po, PDTA_BitMapHeader, (&pbmh), TAG_DONE ) )
{
if( pbmh )
{
ULONG *pcregs;
struct ColorRegister *pcm;
ULONG numcolors = (1UL << animdepth), /* note that numcolors
* may not match ADTA_NumColors
*/
allocated_numcolors;
/* copy bitmapheader (RAW) from animation bmh... */
*pbmh = *abmh;
/* ...and fill in attributes which may be different */
pbmh -> bmh_Width = framewidth;
pbmh -> bmh_Height = frameheight;
pbmh -> bmh_Depth = framedepth;
/* we're writing a full palette, set this flag (currently NOP, but...) */
pbmh -> bmh_Pad = BMHDF_CMAPOK; /* also known as bmh_Flags */
/* Set screen mode id,
* our bitmap and
* the requested number of colors...
*/
SetDTAttrs( po, NULL, NULL,
PDTA_ModeID, amodeid,
PDTA_NumColors, numcolors,
PDTA_BitMap, bm,
TAG_DONE );
/* Get color tables (pcregs, pcm) and the allocated number of colors */
if( GetDTAttrs( po, PDTA_CRegs, (&pcregs),
PDTA_ColorRegisters, (&pcm),
PDTA_NumColors, (&allocated_numcolors),
TAG_DONE ) == 3UL )
{
/* Success ? */
if( pcregs && pcm )
{
ULONG i;
if( allocated_numcolors != numcolors )
{
Printf( "allocated_numcolors %lu != numcolors %lu\n", allocated_numcolors, numcolors );
}
/* get colors (either from frame's colormap or from animation's palette) */
if( alf . alf_CMap )
{
GetRGB32( (alf . alf_CMap), 0UL, (allocated_numcolors - 1UL), pcregs );
}
else
{
for( i = 0UL ; i < allocated_numcolors ; i++ )
{
pcregs[ ((i * 3) + 0) ] = acregs[ ((i * 3) + 0) ]; /* copy r, */
pcregs[ ((i * 3) + 1) ] = acregs[ ((i * 3) + 1) ]; /* g, */
pcregs[ ((i * 3) + 2) ] = acregs[ ((i * 3) + 2) ]; /* b */
}
}
/* copy cregs to colorregisters */
FillColorRegisters( pcm, acregs, allocated_numcolors );
mysprintf( picturefilename, "%s_picture_%05.5lu.ilbm", filepart, timestamp );
Printf( "saving picture: \"%s\"\n", picturefilename );
SaveDTObject( po, NULL, NULL, picturefilename, DTWM_IFF, NULL );
}
else
{
Printf( "picture object mem err (no color tables)\n" );
error = ERROR_NO_FREE_STORE;
}
}
else
{
/* can't get required args from object */
error = ERROR_OBJECT_WRONG_TYPE;
}
/* picture.datatype object will free the bitmap */
bm = NULL;
}
else
{
Printf( "can't get bitmapheader\n" );
error = ERROR_NO_FREE_STORE;
}
}
else
{
/* can't get required args from object */
Printf( "can't get PDTA_BitMapHeader\n" );
error = ERROR_OBJECT_WRONG_TYPE;
}
/* Get rid of the picture object */
DisposeDTObject( po );
}
else
{
Printf( "can't create picture object\n" );
error = IoErr();
}
/* free temp bitmap */
FreeBitMap( bm );
}
else
{
Printf( "can't alloc frame bitmap\n" );
error = ERROR_NO_FREE_STORE;
}
}
/* handle sound/sample data */
if( alf . alf_Sample )
{
if( options[ OPT_SAMPLEPERFRAME ] )
{
mysprintf( samplefilename, "%s_sample_%05.5lu.8svx", filepart, timestamp );
Printf( "saving sample : \"%s\"\n", samplefilename );
SaveSample( samplefilename, (alf . alf_Sample), (alf . alf_SampleLength), (alf . alf_Period), acycles );
}
if( globalsample )
{
if( globalsampleoffset < (globalsamplesize - (1000UL + (alf . alf_SampleLength))) )
{
CopyMem( (alf . alf_Sample), (globalsample + globalsampleoffset), (alf . alf_SampleLength) );
globalsampleoffset += alf . alf_SampleLength;
}
else
{
Printf( "global sample buffer overflow\n" );
error = ERROR_BUFFER_OVERFLOW;
}
}
}
if( ifffilm )
{
if( error = WriteIFFFilmCell( ifffilm, abmh, (alf . alf_BitMap), (alf . alf_Sample), (alf . alf_SampleLength) ) )
{
Printf( "error while writing IFF FILM, aborted\n" );
EndIFFFilm( ifffilm );
CloseIFFFile( ifffilm );
ifffilm = NULL;
}
}
if( clipifffilm )
{
if( error = WriteIFFFilmCell( clipifffilm, abmh, (alf . alf_BitMap), (alf . alf_Sample), (alf . alf_SampleLength) ) )
{
Printf( "error while writing IFF FILM to clipboard, aborted\n" );
EndIFFFilm( clipifffilm );
CloseIFFClipboard( clipifffilm );
clipifffilm = NULL;
}
}
alf . MethodID = ADTM_UNLOADFRAME;
DoMethodA( o, (Msg)(&alf) );
}
/* Get rid of the anim/movie object */
DisposeDTObject( o );
if( globalsample )
{
mysprintf( samplefilename, "%s_sample_global.8svx", filepart );
SaveSample( samplefilename, globalsample, globalsampleoffset, aperiod, acycles );
FreeVec( globalsample );
}
if( ifffilm )
{
EndIFFFilm( ifffilm );
CloseIFFFile( ifffilm );
}
if( clipifffilm )
{
EndIFFFilm( clipifffilm );
CloseIFFClipboard( clipifffilm );
}
}
else
{
/* NewDTObject failed */
error = IoErr();
}
/* Free the allocated memory after ReadArgs */
FreeArgs( rdargs );
}
else
{
/* ReadArgs failed */
error = IoErr();
}
}
else
{
/* can't open required libraries */
error = ERROR_OBJECT_NOT_FOUND;
}
/* Error ? */
if( error )
{
TEXT errbuff[ 256 ];
/* IFFParse error code ? */
if( error < 0L )
{
/* convert IFFParse error to DOS error */
error = ifferr2doserr[ -error - 1 ];
}
if( error >= DTERROR_UNKNOWN_DATATYPE )
{
mysprintf( errbuff, GetDTString( error ), "file" );
}
else
{
Fault( error, NULL, errbuff, sizeof( errbuff ) );
}
Printf( "dumpdtanim: %s\n", errbuff );
}
CloseLibrary( DataTypesBase );
CloseLibrary( IntuitionBase );
CloseLibrary( GfxBase );
CloseLibrary( IconBase );
CloseLibrary( IFFParseBase );
SetIoErr( error );
return( ((error)?(RETURN_ERROR):(RETURN_OK)) );
}
struct IFFHandle *OpenIFFFile( STRPTR file, ULONG mode )
{
struct IFFHandle *iff;
LONG ioerr;
if( file && mode )
{
if( iff = AllocIFF() )
{
/* Set up IFF_File for file I/O. */
if( iff -> iff_Stream = (ULONG)Open( file, mode ) )
{
InitIFFasDOS( iff );
return( iff );
}
else
{
/* Open failed */
ioerr = IoErr();
}
FreeIFF( iff );
}
else
{
/* AllocIFF failed */
ioerr = ERROR_NO_FREE_STORE;
}
}
else
{
/* wrong function args */
ioerr = ERROR_REQUIRED_ARG_MISSING;
}
SetIoErr( ioerr );
return( NULL );
}
BOOL CloseIFFFile( struct IFFHandle *iff )
{
BOOL success = FALSE;
if( iff )
{
success = Close( (BPTR)(iff -> iff_Stream) );
FreeIFF( iff );
}
return( success );
}
struct IFFHandle *OpenIFFClipboard( LONG unit )
{
struct IFFHandle *iff;
LONG ioerr;
if( iff = AllocIFF() )
{
/* Set up IFF_File for clipboard I/O. */
if( iff -> iff_Stream = (ULONG)OpenClipboard( unit ) )
{
InitIFFasClip( iff );
return( iff );
}
else
{
/* couldn't open clipboard */
ioerr = DTERROR_COULDNT_OPEN_CLIPBOARD;
}
FreeIFF( iff );
}
else
{
/* AllocIFF failed */
ioerr = ERROR_NO_FREE_STORE;
}
SetIoErr( ioerr );
return( NULL );
}
void CloseIFFClipboard( struct IFFHandle *iff )
{
if( iff )
{
CloseClipboard( (struct ClipboardHandle *)(iff -> iff_Stream) );
FreeIFF( iff );
}
}
LONG StartIFFFilm( struct IFFHandle *iff, struct BitMapHeader *bmh, ULONG modeid, struct ColorRegister *cm, ULONG numcolors, struct VoiceHeader *vh )
{
LONG error;
if( !(error = OpenIFF( iff, IFFF_WRITE )) )
{
for( ;; ) /* not a loop, used as a jump table */
{
if( error = PushChunk( iff, ID_FILM, ID_LIST, IFFSIZE_UNKNOWN ) )
break;
/* write ILBM props */
{
if( error = PushChunk( iff, ID_ILBM, ID_PROP, IFFSIZE_UNKNOWN ) )
break;
/* write ILBM BMHD (BitMapHeader) */
{
if( error = PushChunk( iff, 0UL, ID_BMHD, IFFSIZE_UNKNOWN ) )
break;
if( WriteChunkBytes( iff, (APTR)bmh, sizeof( struct BitMapHeader ) ) != sizeof( struct BitMapHeader ) )
{
error = IFFERR_WRITE;
break;
}
if( error = PopChunk( iff ) )
break;
}
/* write ILBM CAMG (amiga view mode) */
{
if( error = PushChunk( iff, 0UL, ID_CAMG, IFFSIZE_UNKNOWN ) )
break;
if( WriteChunkBytes( iff, (APTR)(&modeid), sizeof( ULONG ) ) != sizeof( ULONG ) )
{
error = IFFERR_WRITE;
break;
}
if( error = PopChunk( iff ) )
break;
}
/* write ILBM CMAP (global color map) */
{
ULONG i;
if( error = PushChunk( iff, 0UL, ID_CMAP, IFFSIZE_UNKNOWN ) )
break;
for( i = 0UL ; i < numcolors ; i++, cm++ )
{
/* Write R, B, G bytes */
if( WriteChunkBytes( iff, (APTR)cm, 3UL ) != 3UL )
{
error = IFFERR_WRITE;
break;
}
}
/* any error in loop above ? */
if( error )
break;
if( error = PopChunk( iff ) )
break;
}
if( error = PopChunk( iff ) )
break;
}
/* write 8SVX props */
{
if( error = PushChunk( iff, ID_8SVX, ID_PROP, IFFSIZE_UNKNOWN ) )
break;
{
/* write 8SVX VHDR (VoiceHeader) */
{
if( error = PushChunk( iff, 0UL, ID_VHDR, IFFSIZE_UNKNOWN ) )
break;
if( WriteChunkBytes( iff, (APTR)vh, sizeof( struct VoiceHeader ) ) != sizeof( struct VoiceHeader ) )
{
error = IFFERR_WRITE;
break;
}
if( error = PopChunk( iff ) )
break;
}
}
/* a 8SVX CHAN chunk is missing here (animation.datatype does currently not support stereo sound) */
if( error = PopChunk( iff ) )
break;
}
break; /* end of jump table */
}
/* All headers written successfully ? */
if( error == 0L )
{
/* Success ! */
return( 0L );
}
CloseIFF( iff );
}
return( error );
}
void EndIFFFilm( struct IFFHandle *iff )
{
if( iff )
{
LONG error;
if( error = PopChunk( iff ) )
{
Printf( "error while popping IFF FILM LIST %ld\n", error );
}
CloseIFF( iff );
Printf( "IFF FILM sucessfully created\n" );
}
else
{
Printf( "no iff\n" );
}
}
LONG WriteIFFFilmCell( struct IFFHandle *iff, struct BitMapHeader *bmh, struct BitMap *bm, BYTE *sample, ULONG samplelength )
{
LONG error;
for( ;; ) /* not a loop, used as a jump-table */
{
if( error = PushChunk( iff, ID_CELL, ID_CAT, IFFSIZE_UNKNOWN ) )
break;
/* write FORM ILBM */
{
if( error = PushChunk( iff, ID_ILBM, ID_FORM, IFFSIZE_UNKNOWN ) )
break;
/* Write ILBM BODY */
if( error = PutILBMBody( iff, bm, bmh ) )
break;
if( error = PopChunk( iff ) )
break;
}
/* write FORM 8SVX */
{
if( error = PushChunk( iff, ID_8SVX, ID_FORM, IFFSIZE_UNKNOWN ) )
break;
/* Write 8SVX BODY */
if( error = Put8SVXBody( iff, sample, samplelength ) )
break;
if( error = PopChunk( iff ) )
break;
}
if( error = PopChunk( iff ) )
break;
break; /* end of jump-table */
}
return( error );
}
LONG Put8SVXBody( struct IFFHandle *iff, BYTE *sample, ULONG samplelength )
{
LONG error;
/* Write out a BODY chunk header */
if( error = PushChunk( iff, NULL, ID_BODY, IFFSIZE_UNKNOWN ) )
return( error );
if( WriteChunkBytes( iff, sample, samplelength ) != samplelength )
return( IFFERR_WRITE );
/* Finish the chunk */
error = PopChunk( iff );
return( error );
}
/*****************************************************************************/
/* from IFF example code ("iffp/ilbm.h") */
#define RowBytes( w ) ((((w) + 15) >> 4) << 1)
#define RowBits( w ) ((((w) + 15) >> 4) << 4)
LONG PutILBMBody( struct IFFHandle *iff, struct BitMap *bitmap, struct BitMapHeader *bmh )
{
LONG error;
LONG rowBytes = bitmap -> BytesPerRow; /* for source modulo only */
LONG FileRowBytes = RowBytes( (bmh -> bmh_Width) ); /* width to write in bytes */
ULONG planeCnt = bmh -> bmh_Depth; /* number of bit planes including mask */
ULONG iPlane,
iRow;
BYTE *planes[ 24 ]; /* array of ptrs to planes & mask */
/* Copy the ptrs to bit & mask planes into local array "planes" */
for( iPlane = 0 ; iPlane < planeCnt; iPlane++ )
planes[ iPlane ] = (BYTE *)(bitmap -> Planes[ iPlane ]);
/* Write out a BODY chunk header */
if( error = PushChunk( iff, NULL, ID_BODY, IFFSIZE_UNKNOWN ) )
return( error );
/* Write out the BODY contents */
for( iRow = bmh -> bmh_Height ; iRow > 0 ; iRow-- )
{
for( iPlane = 0 ; iPlane < planeCnt ; iPlane++ )
{
/* Write next row.*/
if( WriteChunkBytes( iff, planes[ iPlane ], FileRowBytes ) != FileRowBytes )
return( IFFERR_WRITE );
planes[ iPlane ] += rowBytes; /* Possibly skipping unused bytes */
}
}
/* Finish the chunk */
error = PopChunk( iff );
return( error );
}
/* save datatypes object with matching icon */
ULONG SaveDTObject( Object *dto, struct Window *window, struct Requester *requester, STRPTR filename, ULONG mode, struct TagItem *dtw_AttrList )
{
ULONG retval = 0UL;
if( dto && filename )
{
struct DataType *dtn;
/* Get the object type */
if( GetDTAttrs( dto, DTA_DataType, (&dtn), TAG_DONE ) )
{
BPTR fh;
/* Open new file... */
if( fh = Open( filename, MODE_NEWFILE ) )
{
struct dtWrite dtw;
LONG ioerr;
/* Write... */
dtw . MethodID = DTM_WRITE;
dtw . dtw_GInfo = NULL;
dtw . dtw_FileHandle = fh;
dtw . dtw_Mode = mode;
dtw . dtw_AttrList = dtw_AttrList;
if( retval = DoDTMethodA( dto, window, requester, (Msg)(&dtw) ) )
{
TEXT buffer[ 256 ];
struct DiskObject *dobj;
/* Save IoErr code because following code will clear this */
ioerr = IoErr();
if( dtn )
{
/* Get the an icon for the file */
mysprintf( buffer, "ENV:Sys/def_%.240s", (dtn -> dtn_Header -> dth_BaseName) );
if( (dobj = GetDiskObject( buffer )) == NULL )
{
dobj = GetDefDiskObject( WBPROJECT );
}
}
else
{
dobj = GetDefDiskObject( WBPROJECT );
}
/* If we have an icon, then write it out */
if( dobj )
{
PutDiskObject( filename, dobj );
FreeDiskObject( dobj );
}
}
else
{
/* Save IoErr code because Close will clear this */
ioerr = IoErr();
}
Close( fh );
SetIoErr( ioerr );
}
}
else
{
/* Can't get DTA_DataType */
SetIoErr( ERROR_NO_FREE_STORE );
}
}
else
{
/* wrong function args */
SetIoErr( ERROR_REQUIRED_ARG_MISSING );
}
return( retval );
}
/* save sound sample using a sound.datatype object */
void SaveSample( STRPTR filename, BYTE *sample, ULONG length, ULONG period, ULONG cycles )
{
Object *so;
/* Create sound object and set it up manually (e.g. DTST_RAM) */
if( so = NewDTObject( NULL,
DTA_SourceType, DTST_RAM,
DTA_GroupID, GID_SOUND,
SDTA_Sample, sample,
SDTA_SampleLength, MAX( 1UL, length ),
SDTA_Period, period,
SDTA_Cycles, (ULONG)MAX( cycles, 1UL ),
TAG_DONE ) )
{
struct VoiceHeader *vh;
/* Set up voiceheader, if possible... */
if( GetDTAttrs( so, SDTA_VoiceHeader, (&vh), TAG_DONE ) )
{
if( vh )
{
vh -> vh_OneShotHiSamples = length;
vh -> vh_RepeatHiSamples = 0UL;
vh -> vh_SamplesPerHiCycle = 0UL;
vh -> vh_SamplesPerSec = ((SysBase -> ex_EClockFrequency) * 5UL) / period;
vh -> vh_Octaves = 1UL;
vh -> vh_Compression = CMP_NONE;
vh -> vh_Volume = 0x10000UL;
}
}
/* save the data */
SaveDTObject( so, NULL, NULL, filename, DTWM_IFF, NULL );
/* The given data (e.g. SDTA_Sample) will be freed by the application */
SetDTAttrs( so, NULL, NULL, SDTA_Sample, NULL, TAG_DONE );
/* Get rid of the sound object */
DisposeDTObject( so );
}
}
/* copy 32 bits-per-gun cregs table into struct ColorRegister array */
void FillColorRegisters( struct ColorRegister *cm, ULONG *cregs, ULONG numcolors )
{
if( cm && cregs && numcolors )
{
ULONG i;
for( i = 0UL ; i < numcolors ; i++, cm++ )
{
/* reduce color information from 32 bits down to 8 bits per r, g, b */
cm -> red = (UBYTE)(cregs[ ((i * 3) + 0) ] >> 24UL);
cm -> green = (UBYTE)(cregs[ ((i * 3) + 1) ] >> 24UL);
cm -> blue = (UBYTE)(cregs[ ((i * 3) + 2) ] >> 24UL);
}
}
}
/* Copy bitmaps, (non-)interleaved source to (non-)interleaved destination */
void CopyBitMap( struct BitMap *dest, struct BitMap *src )
{
if( dest && src )
{
PLANEPTR splanes[ 8 ] = { 0 };
PLANEPTR dplanes[ 8 ] = { 0 };
ULONG iRow,
iPlane;
ULONG srcBytes = (IsInterleavedBitMap( src )?
((src -> BytesPerRow) / (src -> Depth)):
(src -> BytesPerRow));
for( iRow = (src -> Rows) ; iRow > 0UL ; iRow-- )
{
for( iPlane = 0UL ; iPlane < (ULONG)(src -> Depth) ; iPlane++ )
{
if( splanes[ iPlane ] == NULL ) splanes[ iPlane ] = src -> Planes[ iPlane ];
if( dplanes[ iPlane ] == NULL ) dplanes[ iPlane ] = dest -> Planes[ iPlane ];
/* Write next row. */
memcpy( dplanes[ iPlane ], splanes[ iPlane ], (size_t)srcBytes );
splanes[ iPlane ] += src -> BytesPerRow;
dplanes[ iPlane ] += dest -> BytesPerRow;
}
}
}
}
void mysprintf( STRPTR buffer, STRPTR fmt, ... )
{
APTR args;
args = (APTR)((&fmt) + 1);
RawDoFmt( fmt, args, (void (*))"\x16\xc0\x4e\x75", buffer );
}
/* Check if given bitmap is interleaved or not. This function works even on non-chip-mem-bitmaps.
* The V39/V40 GetBitMapAttr function don't set the interleaved flag, see above for a future-compatible
* workaround.
*/
BOOL IsInterleavedBitMap( struct BitMap *bm )
{
if( bm )
{
if( (bm -> Depth) > 1U )
{
if( (ULONG)((bm -> Planes[ 1 ]) - (bm -> Planes[ 0 ])) == ((ULONG)(bm -> BytesPerRow) / (ULONG)(bm -> Depth)) )
{
return( TRUE );
}
}
}
return( FALSE );
}